package com.yzs.exam.context;

import com.yzs.exam.entity.User;
import com.yzs.exam.service.UserService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

/**
 * 环境上下文对象：为了让开发人员能够随时随地获取和使用Request、Response、Session等Web容器对象
 * （而不是从controller层作为参数一层层传递下去 -- 麻烦
 * 这里需要用到spring-security包
 * @author yzs
 * @create 2021-03-18 15:28
 */
@Slf4j
@Component
@AllArgsConstructor
public class WebContext {
    private static final String USER_ATTRIBUTES = "USER_ATTRIBUTES";
    private final UserService userService;

    /**
     * RequestContextHolder:持有上下文的Request容器 -- 继承httpServletRequest
     * SCOPE_REQUEST：表示属性只在请求域生效
     * 获取对应的请求设置其属性
     * @param user
     */
    public void setCurrentUser(User user) {
        log.info("设置用户信息到请求上下文中");
        RequestContextHolder.currentRequestAttributes().setAttribute(USER_ATTRIBUTES, user, RequestAttributes.SCOPE_REQUEST);
    }

    /**
     * 通过当前请求获取对应User请求体
     * @return
     */
    public User getCurrentUser() {
        User user = (User) RequestContextHolder.currentRequestAttributes().getAttribute(USER_ATTRIBUTES, RequestAttributes.SCOPE_REQUEST);
        if (null != user) {
            return user;
        } else {
            org.springframework.security.core.userdetails.User springUser = (org.springframework.security.core.userdetails.User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            if (null == springUser) {
                return null;
            }
            user = userService.getUserByUserName(springUser.getUsername());
            if (null != user) {
                setCurrentUser(user);
            }
            return user;
        }
    }
}
